﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace MusicRenamer {
    public partial class Form1 : Form {
        private String fileFormat;
        private List<String> fileList = new List<string>();
        public String[] audioFormats = { "mp3", "m4a", "flac", "wma", "wav", "ogg", "3gp", "aac", "aiff" };
        public Form1() {
            InitializeComponent();

        }

        private void Form1_Load(object sender, EventArgs e) {
            textBox1.Enabled = false;
        }

        private void button1_Click(object sender, EventArgs e) {
            bool ignore = false;
            progressBar1.Value = 0;
            fileList.Clear();
            if(textBox1.Text != "") {
                if(folderBrowserDialog1.ShowDialog() == DialogResult.OK) {
                    String path = folderBrowserDialog1.SelectedPath;
                    foreach(String format in audioFormats) {
                        fileList.AddRange(System.IO.Directory.GetFiles(path, "*." + format, System.IO.SearchOption.AllDirectories));
                    }
                    for(int i = 0; i < fileList.Count; i++) {
                        progressBar1.Maximum = fileList.Count;
                        progressBar1.PerformStep();
                        String fileName = fileList[i];
                        String parsedFile = parseName(TagLib.File.Create(fileName));
                        if(parsedFile == "ABORTED") {
                            progressBar1.Value = 0;
                            return;
                        }
                        if(parsedFile == "RETRY") {
                            i--;
                            continue;
                        }
                        if(parsedFile == "IGNORE")
                            continue;
                        if(fileName.Equals(parsedFile)) {
                            continue;
                        }
                        while(true) {
                            try {
                                System.IO.File.Move(fileName, System.IO.Directory.GetParent(fileName).FullName + "\\" + parsedFile + System.IO.Path.GetExtension(fileName));
                                break;
                            }
                            catch(System.IO.IOException ee) {
                                switch(System.Windows.Forms.MessageBox.Show(ee.Message, "Error", System.Windows.Forms.MessageBoxButtons.AbortRetryIgnore, System.Windows.Forms.MessageBoxIcon.Error)) {
                                    case System.Windows.Forms.DialogResult.Abort:
                                        return;
                                    case System.Windows.Forms.DialogResult.Retry:
                                        continue;
                                    case System.Windows.Forms.DialogResult.Ignore:
                                        ignore = true;
                                        break;
                                }
                            }
                            if(ignore) {
                                break;
                            }
                        }
                        if(ignore) {
                            continue;
                        }
                    }
                }
            }
            else {
                System.Windows.Forms.MessageBox.Show("Please select a renaming style");
            }
        }

        private void comboBox1_SelectedIndexChanged(object sender, EventArgs e) {
            textBox1.Enabled = comboBox1.SelectedIndex == 2 ? true : false;
            switch(comboBox1.SelectedIndex) {
                case 0:
                    textBox1.Text = "$track $title";
                    fileFormat = textBox1.Text;
                    textBox1_TextChanged(null, null);
                    break;
                case 1:
                    textBox1.Text = "$track. $title";
                    fileFormat = textBox1.Text;
                    textBox1_TextChanged(null, null);
                    break;
                case 2:
                    textBox1.Text = "";
                    Form2 form = new Form2();
                    form.Show();
                    break;
            }
        }

        private void textBox1_TextChanged(object sender, EventArgs e) {
            fileFormat = textBox1.Text;
            String exampleText = fileFormat + ".mp3";
            exampleText = exampleText.Replace("$track", "01");
            exampleText = exampleText.Replace("$title", "Test");
            exampleText = exampleText.Replace("$artist", "Kenny Tang");
            exampleText = exampleText.Replace("$album", "Example [Deluxe]");
            exampleText = exampleText.Replace("$genre", "");
            exampleText = exampleText.Replace("$year", "2015");
            exampleText = exampleText.Replace("$length", "13:37");
            label2.Text = "Preview: " + exampleText;
        }
        //Fills in wildcards into the full name
        private String parseName(TagLib.File musicInfo) {
            String fileName = fileFormat;
            //$track, $title, $artist, $album, $genre, $year, $length
            if(fileName.Contains("$track")) {
                if(musicInfo.Tag.Track != 0) {
                    fileName = fileName.Replace("$track", musicInfo.Tag.Track < 10 ? "0" + musicInfo.Tag.Track.ToString() : musicInfo.Tag.Track.ToString());
                }
                else {
                    switch(System.Windows.Forms.MessageBox.Show("Error: Track # missing from tag info (Tag info may also be corrupt) File:" + musicInfo.Name, "Error", System.Windows.Forms.MessageBoxButtons.AbortRetryIgnore, System.Windows.Forms.MessageBoxIcon.Error)) {
                        case System.Windows.Forms.DialogResult.Abort:
                            fileName = "ABORTED";
                            return fileName;
                        case System.Windows.Forms.DialogResult.Retry:
                            fileName = "RETRY";
                            return fileName;
                        case System.Windows.Forms.DialogResult.Ignore:
                            fileName = "IGNORE";
                            return fileName;
                    }

                }
            }
            if(fileName.Contains("$title")) {
                if(!musicInfo.Tag.Title.Equals("")) {
                    fileName = fileName.Replace("$title", musicInfo.Tag.Title);
                }
                else {
                    switch(System.Windows.Forms.MessageBox.Show("Error: Title missing from tag info File:" + musicInfo.Name, "Error", System.Windows.Forms.MessageBoxButtons.AbortRetryIgnore, System.Windows.Forms.MessageBoxIcon.Error)) {
                        case System.Windows.Forms.DialogResult.Abort:
                            fileName = "ABORTED";
                            return fileName;
                        case System.Windows.Forms.DialogResult.Retry:
                            fileName = "RETRY";
                            return fileName;
                        case System.Windows.Forms.DialogResult.Ignore:
                            fileName = "IGNORE";
                            return fileName;
                    }
                }
            }
            if(fileName.Contains("$artist")) {
                if(!musicInfo.Tag.JoinedPerformers.Equals("")) {
                    fileName = fileName.Replace("$artist", musicInfo.Tag.JoinedPerformers);
                }
                else {
                    switch(System.Windows.Forms.MessageBox.Show("Error: Artist(s) missing from tag info File:" + musicInfo.Name, "Error", System.Windows.Forms.MessageBoxButtons.AbortRetryIgnore, System.Windows.Forms.MessageBoxIcon.Error)) {
                        case System.Windows.Forms.DialogResult.Abort:
                            fileName = "ABORTED";
                            return fileName;
                        case System.Windows.Forms.DialogResult.Retry:
                            fileName = "RETRY";
                            return fileName;
                        case System.Windows.Forms.DialogResult.Ignore:
                            fileName = "IGNORE";
                            return fileName;
                    }
                }
            }
            if(fileName.Contains("$album")) {
                if(!musicInfo.Tag.Album.Equals("")) {
                    fileName = fileName.Replace("$album", musicInfo.Tag.Album);
                }
                else {
                    switch(System.Windows.Forms.MessageBox.Show("Error: Album missing from tag info File:" + musicInfo.Name, "Error", System.Windows.Forms.MessageBoxButtons.AbortRetryIgnore, System.Windows.Forms.MessageBoxIcon.Error)) {
                        case System.Windows.Forms.DialogResult.Abort:
                            fileName = "ABORTED";
                            return fileName;
                        case System.Windows.Forms.DialogResult.Retry:
                            fileName = "RETRY";
                            return fileName;
                        case System.Windows.Forms.DialogResult.Ignore:
                            fileName = "IGNORE";
                            return fileName;
                    }
                }
            }
            if(fileName.Contains("$genres")) { 
                if(!musicInfo.Tag.JoinedGenres.Equals("")) {
                    fileName = fileName.Replace("$genres", musicInfo.Tag.JoinedGenres);
                }
                else {
                    switch(System.Windows.Forms.MessageBox.Show("Error: Genre(s) missing from tag info File:" + musicInfo.Name, "Error", System.Windows.Forms.MessageBoxButtons.AbortRetryIgnore, System.Windows.Forms.MessageBoxIcon.Error)) {
                        case System.Windows.Forms.DialogResult.Abort:
                            fileName = "ABORTED";
                            return fileName;
                        case System.Windows.Forms.DialogResult.Retry:
                            fileName = "RETRY";
                            return fileName;
                        case System.Windows.Forms.DialogResult.Ignore:
                            fileName = "IGNORE";
                            return fileName;
                    }
                }
            }
            if(fileName.Contains("$year")) { 
                if(musicInfo.Tag.Year != 0) {
                    fileName = fileName.Replace("$year", musicInfo.Tag.Year.ToString());
                }
                else {
                    switch(System.Windows.Forms.MessageBox.Show("Error: Year missing from tag info File:" + musicInfo.Name, "Error", System.Windows.Forms.MessageBoxButtons.AbortRetryIgnore, System.Windows.Forms.MessageBoxIcon.Error)) {
                        case System.Windows.Forms.DialogResult.Abort:
                            fileName = "ABORTED";
                            return fileName;
                        case System.Windows.Forms.DialogResult.Retry:
                            fileName = "RETRY";
                            return fileName;
                        case System.Windows.Forms.DialogResult.Ignore:
                            fileName = "IGNORE";
                            return fileName;
                    }
                }
            }
            if(checkBox1.Checked) {
                var title = Clone(musicInfo.Tag.Title);
                var artist = Clone(musicInfo.Tag.Performers);
                var albartist = Clone(musicInfo.Tag.AlbumArtists);
                var genre = Clone(musicInfo.Tag.Genres);
                var album = Clone(musicInfo.Tag.Album);
                var year = musicInfo.Tag.Year;
                var track = musicInfo.Tag.Track;
                musicInfo.Tag.Clear();
                musicInfo.Tag.Title = (String)title;
                musicInfo.Tag.Performers = (String[])artist;
                musicInfo.Tag.AlbumArtists = (String[])albartist;
                musicInfo.Tag.Genres = (String[])genre;
                musicInfo.Tag.Album = (String)album;
                musicInfo.Tag.Year = year;
                musicInfo.Tag.Track = track;
                while(true) {
                    try {
                        musicInfo.Save();
                        break;
                    }
                    catch(System.IO.IOException e) {
                        System.Windows.Forms.MessageBox.Show(e.Message);
                    }
                }
            }
            fileName = fileName.Replace("\\", "");
            fileName = fileName.Replace("/", "");
            fileName = fileName.Replace(":", "");
            fileName = fileName.Replace("*", "");
            fileName = fileName.Replace("?", "");
            fileName = fileName.Replace("\"", "");
            fileName = fileName.Replace("<", "");
            fileName = fileName.Replace(">", "");
            fileName = fileName.Replace("|", "");
            return fileName;
            
        }

        private object Clone(ICloneable toClone) {
            if(toClone != null) {
                return toClone.Clone();
            }
            return null;
        }

        private void exitToolStripMenuItem_Click(object sender, EventArgs e) {
            Close();
        }

        private void audioFormatsToolStripMenuItem_Click(object sender, EventArgs e) {
            Form3 form = new Form3();
            form.listAudio(audioFormats);
            if(form.ShowDialog() == DialogResult.OK) {
                audioFormats = form.fileExtensions;
            }
            form.Dispose();
            
        }
    }
}
